#include <stdio.h>
#include <glib-object.h>

#define entry printf("%s++\n", __FUNCTION__)
#define exit printf("%s--\n", __FUNCTION__)

#define FOO_TYPE (foo_get_type())
#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), FOO_TYPE, Foo))

typedef struct _Foo Foo;
typedef struct _FooClass FooClass;

struct _Foo
{
    GObject parent_instance;
};

struct _FooClass
{
    GObjectClass parent_class;
};

/**
  Will create foo_get_type and set foo_parent_class. G_TYPE_OBJECT is the parent
  of Foo.

  G_TYPE_OBJECT is the fundamental type of GObject.
  */
G_DEFINE_TYPE (Foo, foo, G_TYPE_OBJECT);

static GObject* 
foo_constructor(
        GType gtype,
        guint n_properties,
        GObjectConstructParam* properties
        )
{
    GObject* obj;

    entry;

    {
        //
        // The g_object_constructor method invoked by the last ctor in the chain
        // allocates object's instance buffer through g_type_create_instance
        // which means that instance_init (foo_init) will be called to complete
        // the initialization of the object.
        //

        obj = G_OBJECT_CLASS(foo_parent_class)->constructor(gtype, n_properties,
                properties);
    }

    exit;

    return obj;
}

/**
  Called during 1st instantiation of Foo objects.

  This method is expected to override object's class methods and set up class'
  own methods. 

  */
static void
foo_class_init(
        FooClass* klass
        )
{
    entry;
  
    GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
    
    //
    // Sets the constructor to foo_constructor.
    //

    gobject_class->constructor = foo_constructor;
    
    exit;
}

static void
foo_init(
        Foo* self
        )
{
    entry;
    exit;
}
    
int
main (int argc, char* argv[])
{
    g_type_init();
    
    Foo* foo_obj = g_object_new(FOO_TYPE, NULL);
    
    return 0;
}

